package cn.lili.modules.kit.plugin.alipay;

import cn.hutool.json.JSONUtil;
import cn.lili.common.context.ThreadContextHolder;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.DomainProperties;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.GsonUtils;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.vo.ResultMessage;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.kit.Payment;
import cn.lili.modules.kit.plugin.wallet.WalletPlugin;
import cn.lili.modules.kit.plugin.wechat.model.PartnerTransactionsResult;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.payment.entity.dos.OutOrderLog;
import cn.lili.modules.payment.entity.dos.PaymentData;
import cn.lili.modules.payment.entity.dos.PaymentLog;
import cn.lili.modules.payment.entity.dos.RefundLog;
import cn.lili.modules.payment.entity.dto.PayParamItem;
import cn.lili.modules.payment.entity.dto.PaymentCallback;
import cn.lili.modules.payment.entity.dto.PaymentWakeupParam;
import cn.lili.modules.payment.entity.enums.PaymentMethodEnum;
import cn.lili.modules.payment.entity.enums.PaymentSceneEnums;
import cn.lili.modules.payment.service.*;
import cn.lili.modules.payment.wechat.enums.AlipayDomain;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.payment.AlipayPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.wallet.service.WalletService;
import cn.lili.routing.PaymentRoutingKey;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import cn.lili.common.properties.ApiProperties;

import javax.annotation.Resource;
import javax.json.Json;
import java.math.BigDecimal;
import java.util.Map;

@Slf4j
@Component
public class AliPayPluginNew extends WalletPlugin implements Payment {

    @Resource
    private ApiProperties apiProperties;
    @Resource
    private AliPayPluginNewManage aliPayPluginNewManage;
    @Resource
    private PaymentDataService paymentDataService;

    public AliPayPluginNew(ApplicationEventPublisher applicationEventPublisher,
                           AmqpExchangeProperties amqpExchangeProperties, WalletService walletService,
                           PaymentLogService paymentLogService, OutOrderLogService outOrderLogService,
                           OutOrderDetailLogService outOrderDetailLogService,
                           PaymentSubsidiesService paymentSubsidiesService,
                           PaymentUrbanSubstationCommissionService paymentUrbanSubstationCommissionService, OrderClient orderClient) {
        super(applicationEventPublisher, amqpExchangeProperties, walletService, paymentLogService,
                outOrderLogService, outOrderDetailLogService, paymentSubsidiesService,
                paymentUrbanSubstationCommissionService, orderClient);
    }

    /**
     * H5支付
     */
    @Override
    public ResultMessage<Object> h5pay(PaymentWakeupParam paymentWakeupParam) {
        //获取支付配置
        AlipayPaymentSetting setting = aliPayPluginNewManage.alipayPaymentSetting();
        String appId = setting.getAppId();
        String privateKey = setting.getPrivateKey();
        String publicKey = setting.getPublicKey();

        //组织请求支付参数
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayDomain.OPENAPI_GATEWAY.toString(), appId, privateKey, "json", "UTF-8", publicKey, "RSA2");
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

        //异步接收地址，仅支持http/https，公网可访问
        request.setNotifyUrl(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.ALIPAY));

        if (PaymentSceneEnums.VIP.name().equals(paymentWakeupParam.getPayParam().getPaymentSceneEnums().name())) {
            request.setReturnUrl(syncVipUrl(apiProperties.getH5url()));
        }else {
            //request.setReturnUrl(syncUrl(apiProperties.getH5url()) + "?order_id=" + paymentWakeupParam.getOrderSn());
            request.setReturnUrl(syncUrl(apiProperties.getH5url()) + "?payMethod=ALIPAY");
        }


        //同步跳转地址，仅支持http/https
        AlipayTradeWapPayResponse response;
        try {
            if(Boolean.TRUE.equals(paymentWakeupParam.getIsCombine())) {
                JSONObject bizContent = aliPayPluginNewManage.mergePublicPay(paymentWakeupParam);
                request.setBizContent(bizContent.toJSONString());
            }else{
                JSONObject bizContent = aliPayPluginNewManage.publicPay(paymentWakeupParam);
                request.setBizContent(bizContent.toJSONString());
            }
            response = alipayClient.pageExecute(request);

            //保存发送数据
            PaymentData paymentData = new PaymentData();
            paymentData.setOrderSn(paymentWakeupParam.getOrderSn());
            paymentData.setPayType(2);
            paymentData.setSendBody(com.alibaba.fastjson.JSONObject.toJSONString(request));
            paymentData.setResBody(com.alibaba.fastjson.JSONObject.toJSONString(response));
            paymentDataService.save(paymentData);
            log.info("paymentData save data == {}", com.alibaba.fastjson.JSONObject.toJSONString(paymentData));
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        return ResultUtil.data(JSONUtil.toJsonStr(response.getBody()));
    }

    /**
     * 支付成功回调
     */
    @Override
    public void paymentNotify() {
        try {
            AlipayPaymentSetting alipayPaymentSetting = aliPayPluginNewManage.alipayPaymentSetting();
            //获取支付宝反馈信息
            Map<String, String> map = AliPayApi.toMap(ThreadContextHolder.getHttpRequest());
            log.info("同步回调：{}", JSONUtil.toJsonStr(map));
            boolean verifyResult = AlipaySignature.rsaCheckV1(map, alipayPaymentSetting.getPublicKey(), "UTF-8", "RSA2");
            //支付完成判定
            if (!"TRADE_FINISHED".equals(map.get("trade_status")) && !"TRADE_SUCCESS".equals(map.get("trade_status"))) {
                return;
            }

            JSONObject payParamJson = JSONObject.parseObject(map.get("passback_params"));
            if (verifyResult) {
                log.info("支付回调通知：支付成功-参数：{}", map);
                if (Boolean.parseBoolean(payParamJson.get("isCombine").toString())) {
                    //合单回调
                    aliPayPluginNewManage.mergePublicNotify(map);
                } else {
                    //普通订单回调
                    aliPayPluginNewManage.publicNotify(map);
                }
                /*if (payParamJson.containsKey("scene") && PaymentSceneEnums.VIP.name().equals(payParamJson.getString("scene"))) {
                    log.info("alipay-VIP回调");
                    aliPayPluginNewManage.vipNotify(map);
                }else if (payParamJson.containsKey("scene") && PaymentSceneEnums.AUDIT.name().equals(payParamJson.getString("scene"))) {
                    log.info("alipay-AUDIT回调");
                    aliPayPluginNewManage.auditNotify(map);
                }else {
                    if (Boolean.parseBoolean(payParamJson.get("isCombine").toString())) {
                        //合单回调
                        aliPayPluginNewManage.mergePublicNotify(map);
                    } else {
                        //普通订单回调
                        aliPayPluginNewManage.publicNotify(map);
                    }
                }*/
            } else {
                log.info("支付回调通知：支付失败-参数：{}", map);
            }
        } catch (Exception e) {
            log.error("支付回调同步通知异常", e);
        }
    }

    /**
     * 退款
     *
     * @param refundLog 退款请求参数
     */
    @Override
    public void refund(RefundLog refundLog){
        log.info("退款了----------------");
        log.info("退款了----------------" + JSONObject.toJSONString(refundLog));
        //获取支付配置
        AlipayPaymentSetting setting = aliPayPluginNewManage.alipayPaymentSetting();
        String appId = setting.getAppId();
        String privateKey = setting.getPrivateKey();
        String publicKey = setting.getPublicKey();

        //组织请求参数
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayDomain.OPENAPI_GATEWAY.toString(), appId, privateKey, "json", "UTF-8", publicKey, "RSA2");
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("trade_no", refundLog.getTransactionId());
        bizContent.put("refund_amount", refundLog.getPrice());
        bizContent.put("out_request_no", refundLog.getAfterSaleNo());

        AlipayTradeRefundResponse response;
        request.setBizContent(bizContent.toString());

        log.info("退款了----------------" + JSONObject.toJSONString(request));
        try {
            response = alipayClient.execute(request);

        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        if(response.isSuccess()){
            refundLog.setIsRefund(true);
            refundLog.setRefundTransactionId(refundLog.getTransactionId());
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            throw new ServiceException("退款失败");
        }
    }
}
